package com.fleet.project01.data.api;

import com.fleet.project01.utils.LogUtils;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;

/**
 * HTTP请求和响应日志拦截器
 * 用于打印网络请求的详细信息，包括URL、请求参数、响应数据等
 */
public class LoggingInterceptor implements Interceptor {
    private static final String TAG = "HTTP_LOG";
    private static final Charset UTF8 = StandardCharsets.UTF_8;

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        
        // 记录请求开始时间
        long startTime = System.currentTimeMillis();
        
        // 打印请求信息
        logRequest(request);
        
        // 执行请求
        Response response = chain.proceed(request);
        
        // 计算请求耗时
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        
        // 打印响应信息并返回处理后的响应
        return logResponse(response, duration);
    }

    /**
     * 打印请求信息
     */
    private void logRequest(Request request) {
        try {
            LogUtils.d(TAG, "========== 请求开始 ==========");
            LogUtils.d(TAG, "请求方法: " + request.method());
            LogUtils.d(TAG, "请求地址: " + request.url());
            
            // 打印请求头
            if (request.headers().size() > 0) {
                LogUtils.d(TAG, "请求头:");
                for (int i = 0; i < request.headers().size(); i++) {
                    String name = request.headers().name(i);
                    String value = request.headers().value(i);
                    LogUtils.d(TAG, "  " + name + ": " + value);
                }
            }
            
            // 打印请求体
            RequestBody requestBody = request.body();
            if (requestBody != null) {
                LogUtils.d(TAG, "请求体类型: " + requestBody.contentType());
                LogUtils.d(TAG, "请求体大小: " + requestBody.contentLength() + " bytes");
                
                // 打印请求体内容
                if (isPlaintext(requestBody.contentType())) {
                    Buffer buffer = new Buffer();
                    requestBody.writeTo(buffer);
                    
                    Charset charset = UTF8;
                    MediaType contentType = requestBody.contentType();
                    if (contentType != null && contentType.charset() != null) {
                        charset = contentType.charset();
                    }
                    
                    if (buffer.size() > 0) {
                        LogUtils.d(TAG, "请求体内容:");
                        LogUtils.d(TAG, buffer.clone().readString(charset));
                    }
                }
            }
            
            LogUtils.d(TAG, "========== 请求结束 ==========");
            
        } catch (Exception e) {
            LogUtils.e(TAG, "打印请求信息失败: " + e.getMessage());
        }
    }

    /**
     * 打印响应信息并返回新的响应对象
     */
    private Response logResponse(Response response, long duration) {
        try {
            LogUtils.d(TAG, "========== 响应开始 ==========");
            LogUtils.d(TAG, "响应地址: " + response.request().url());
            LogUtils.d(TAG, "响应状态: " + response.code() + " " + response.message());
            LogUtils.d(TAG, "请求耗时: " + duration + "ms");
            
            // 打印响应头
            if (response.headers().size() > 0) {
                LogUtils.d(TAG, "响应头:");
                for (int i = 0; i < response.headers().size(); i++) {
                    String name = response.headers().name(i);
                    String value = response.headers().value(i);
                    LogUtils.d(TAG, "  " + name + ": " + value);
                }
            }
            
            // 打印响应体
            ResponseBody responseBody = response.body();
            if (responseBody != null) {
                LogUtils.d(TAG, "响应体类型: " + responseBody.contentType());
                LogUtils.d(TAG, "响应体大小: " + responseBody.contentLength() + " bytes");
                
                // 打印响应体内容
                if (isPlaintext(responseBody.contentType())) {
                    String responseString = responseBody.string();
                    LogUtils.d(TAG, "响应体内容:");
                    LogUtils.d(TAG, responseString);
                    
                    // 重新创建ResponseBody，因为string()方法会消耗掉body
                    MediaType contentType = responseBody.contentType();
                    ResponseBody newResponseBody = ResponseBody.create(contentType, responseString);
                    
                    // 返回新的response，包含重新创建的body
                    LogUtils.d(TAG, "========== 响应结束 ==========");
                    return response.newBuilder()
                            .body(newResponseBody)
                            .build();
                }
            }
            
            LogUtils.d(TAG, "========== 响应结束 ==========");
            
        } catch (Exception e) {
            LogUtils.e(TAG, "打印响应信息失败: " + e.getMessage());
        }
        
        // 如果没有处理响应体或发生异常，返回原始响应
        return response;
    }

    /**
     * 判断是否为纯文本类型
     */
    private boolean isPlaintext(MediaType mediaType) {
        if (mediaType == null) return false;
        
        String type = mediaType.type();
        String subtype = mediaType.subtype();
        
        // 判断是否为文本类型
        if ("text".equals(type)) {
            return true;
        }
        
        // 判断是否为JSON类型
        if ("application".equals(type)) {
            return "json".equals(subtype) || 
                   "javascript".equals(subtype) || 
                   subtype.endsWith("+json");
        }
        
        // 判断是否为XML类型
        if ("application".equals(type)) {
            return "xml".equals(subtype) || 
                   subtype.endsWith("+xml");
        }
        
        return false;
    }
}
